import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test {
    public static void main(String[] args) {
        // 仍然先定义了接口Hello，但是我们并不去编写实现类，而是直接通过JDK提供的一个Proxy.newProxyInstance()创建了一个Hello接口对象。
        // 这种没有实现类但是在运行期动态创建了一个接口对象的方式，我们称为动态代码
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                if (method.getName().equals("morning")) {
                    System.out.println("Good morning, " + args[0]);
                }
                return null;
            }
        };
        Hello hello = (Hello) Proxy.newProxyInstance(
            Hello.class.getClassLoader(), // 传入ClassLoader
            new Class[] { Hello.class }, // 传入要实现的接口
            handler); // 传入处理调用方法的InvocationHandler
        hello.morning("Bob");
    }
}

interface Hello {
    void morning(String name);
}

// 类似动态生成如下代码
// public class HelloDynamicProxy implements Hello {
//     InvocationHandler handler;
//     public HelloDynamicProxy(InvocationHandler handler) {
//         this.handler = handler;
//     }
//     public void morning(String name) {
//         handler.invoke(
//            this,
//            Hello.class.getMethod("morning", String.class),
//            new Object[] { name }
//         );
//     }
// }